package tests.user;

import tests.user.Sampler.Insider;
import tester.*;
import tester.utilities.Printer;

import java.util.*;
import java.awt.Color;

/**
 * Copyright 2007, 2008 Viera K. Proulx
 * This program is distributed under the terms of the 
 * GNU Lesser General Public License (LGPL)
 */

/**
 * A class to demonstrate and test the use of the test harness.
 *  
 * @author Viera K. Proulx
 * @since 20 March 2008, 11 November 2008
 *
 */
@Example
public class Examples{
  
  Examples(){}
 
   
  //------------ Examples and Tests for user-defined classes ------------//
  
  /** Sample data: <CODE>{@link Author Author}</CODE> -- implements
   *  <CODE>{@link ISame ISame}</CODE> interface to compare names only */
  public Author author1=new Author("author1",40);
  public Author author2=new Author("author2",55);
  public Author author3=new Author("author3",66);
  public Author author4=new Author("author4",26);
  
  /** Sample data: <CODE>{@link Book Book}</CODE> -- 
   * illustrates object containment 
   */
  public Book book1=new Book("title1",author1,4000); 
  public Book book2=new Book("title2",author2,4000);
  public Book book3=new Book("title3",author3,3001);
  public Book book4=new Book("title4",author4,4000);

  /** Sample data: <CODE>{@link Song Song}</CODE> -- a class used in lists, 
   * <CODE>{@link Traversal Traversal}</CODE>Traversal, 
   * <code>ArrayList</code examples
   */
  public Song song1=new Song("title1",4);
  public Song song2=new Song("title2",2);
  public Song song3=new Song("title3",3);
  public Song song1a=new Song("title1",4);
  
  
  /**
   * Test the correct comparisons of classes with the object containment.
   * Test the correct invocation of the user-defined 'same' method
   * in the class <CODE>{@link Author Author}</CODE>
   * 
   * @param t the <CODE>{@link Tester Tester}</CODE> that performs the tests
   */
  @TestMethod
  public boolean testAuthors(Tester t){
    return

    // Examples of tests with explicit comparison using 'same' method 
    // in the Tester class -- useful when we expect a failure
    // -- will not show the compared values - only the boolean result
    t.checkExpect(t.same(song1, song1), true, "same songs 1") &&
    t.checkExpect(t.same(song2, song1), false, "same songs 2") &&
    t.checkExpect(t.same(song1a, song1), true, "same songs 3") &&
    
    // Tests for the Book class //
    t.checkExpect(book1, 
                  new Book("title1", new Author("author1", 40), 4000),
                  "test the comparison of two Book objects: ") &&
    t.checkExpect(book1.title, "title1",
                  "test the comparison on a field within an object") &&
    t.checkExpect(book1.changeAuthor(author2), 
                  new Book("title1", new Author("author2", 55), 4000),
                  "test the method 'changeAuthor' in the class Book: ") &&
    
    // Tests for the Author class //
    t.checkExpect(author1, new Author("author1",40), "same author") &&
    t.checkExpect(author1, new Author("author1",36),
        "same author, different age -- expect OK by user-defined 'same': ");
  }


  //------ Examples and Tests for user-defined class hierarchies ------//
  /** Sample data: Empty lists for each type */
  public AList<Author> mtAuthor= new MTList<Author>();
  public AList<Book> mtBook= new MTList<Book>();
  public AList<Song> mtSong= new MTList<Song>();

  /** Sample data: A list of <CODE>{@link Book Book}</CODE> */
  public AList<Book> booklist= new ConsList<Book>(book1, 
      new ConsList<Book>(book2,
          new ConsList<Book>(book3, 
              mtBook))); 
  
  /** Sample data: A list of <CODE>{@link Song Song}</CODE> */
  public AList<Song> songlist= new ConsList<Song>(song1, 
      new ConsList<Song>(song2,
          new ConsList<Song>(song3, 
              mtSong)));

  /** Sample data: A list of <CODE>{@link Song Song}</CODE> 
   * with data in a different order */
  public AList<Song> songlist1= new ConsList<Song>(song1, 
      new ConsList<Song>(song3,
          new ConsList<Song>(song2, 
              mtSong)));

  /** Sample data: A list of <CODE>{@link Song Song}</CODE> 
   * with the same data as the original */
  public AList<Song> songlist2= new ConsList<Song>(song1, 
      new ConsList<Song>(song2,
          new ConsList<Song>(song3, 
              mtSong)));

  /** Sample data: A list of <CODE>{@link Song Song}</CODE> 
   * that is shorter */
  public AList<Song> songlist3= new ConsList<Song>(song1, 
      new ConsList<Song>(song2,
          mtSong));

  //------ Examples and Tests for datasets generated by Traversal-s ------//
  /** Sample data: A <CODE>{@link Traversal Traversal}</CODE> over a 
   * list of <CODE>{@link Book Book}</CODE> */
  public Traversal<Book> booklistTr= new ConsListTr<Book>(book1, 
      new ConsListTr<Book>(book2,
          new ConsListTr<Book>(book3, 
              new MTListTr<Book>())));
  
  /** Sample data: A <CODE>{@link Traversal Traversal}</CODE> over 
   * a list of <CODE>{@link Song Song}</CODE> */
  public Traversal<Song> songlistTr = new ConsListTr<Song>(song1, 
      new ConsListTr<Song>(song2,
          new ConsListTr<Song>(song3, 
              new MTListTr<Song>())));

  /** Sample data: A <CODE>{@link Traversal Traversal}</CODE> over 
   * a list of <CODE>{@link Song Song}</CODE> with different data */
  public Traversal<Song> songlistTr1 = new ConsListTr<Song>(song1, 
      new ConsListTr<Song>(song3,
          new ConsListTr<Song>(song2, 
              new MTListTr<Song>())));

  /** Sample data: A <CODE>{@link Traversal Traversal}</CODE> over 
   * a list of <CODE>{@link Song Song}</CODE> with the same data */
  public Traversal<Song> songlistTr2 = new ConsListTr<Song>(song1, 
      new ConsListTr<Song>(song2,
          new ConsListTr<Song>(song3, 
              new MTListTr<Song>())));

  /** Sample data: A <CODE>{@link Traversal Traversal}</CODE> over 
   * a shorter list of <CODE>{@link Song Song}</CODE> */
  public Traversal<Song> songlistTr3 = new ConsListTr<Song>(song1, 
      new ConsListTr<Song>(song2,
          new MTListTr<Song>()));
 
  
  
  /**
   * <P>Test the correct comparisons of data generated by the 
   * <code>Traversal<T></code></P>
   * <P>Expects that the two class implementing the <code>Traversal<T></code> 
   * are the same.
   * 
   * @param t the <code>Tester</code> that performs the tests
   */
  @TestMethod
  public boolean testTraversals(Tester t){
    return

    t.checkExpect(t.same(songlistTr, songlistTr2), true,
        "same songlist generated by Traversal") &&
    t.checkExpect(songlistTr, songlistTr2,
        "same songlist generated by Traversal - direct") &&
    t.checkExpect(t.same(songlistTr, songlistTr3), false,
        "different songlists generated by Traversal:  first one is longer") &&
    t.checkExpect(t.same(songlistTr3, songlistTr2), false,
        "different songlists generated by Traversal:  first one is shorter") &&
    t.checkExpect(t.same(songlistTr, songlistTr1), false,
        "different songlists generated by Traversal: data is different") &&
    t.checkExpect(t.same(songlistTr, booklistTr), false,
        "different songlists generated by Traversal: different datatypes") &&
    t.checkFail(songlistTr, booklistTr,
        "different songlists generated by Traversal: different datatypes");
  }

  //--- Examples and Tests for datasets that implement Iterable interface ---//
  /** Sample data: An <code>ArrayList</code> 
   * of <CODE>{@link Song Song}</CODE> */
  public ArrayList<Song> songlistAL= new ArrayList<Song>(3);
  public void initSonglistAL(){
    songlistAL.add(song1);
    songlistAL.add(song2);
    songlistAL.add(song3);
  }
 
  /** Sample data: An An <code>ArrayList</code> 
   * of <CODE>{@link Song Song}</CODE> with the same data */
  public ArrayList<Song> songlist2AL= new ArrayList<Song>(3);
  public void initSonglist2AL(){
    songlist2AL.add(song1);
    songlist2AL.add(song2);
    songlist2AL.add(song3);
  }
  
  /** Sample data: A shorter An <code>ArrayList</code> 
   * of <CODE>{@link Song Song}</CODE> */
  public ArrayList<Song> songlist3AL= new ArrayList<Song>(3);
  public void initSonglist3AL(){
    songlist3AL.add(song1);
    songlist3AL.add(song2);
  }
  
  /** Sample data: An An <code>ArrayList</code> 
   * of <CODE>{@link Song Song}</CODE> -- different order of data */
  public ArrayList<Song> songlist4AL= new ArrayList<Song>(3);
  public void initSonglist4AL(){
    songlist4AL.add(song1);
    songlist4AL.add(song3);
    songlist4AL.add(song2);
  }
  
  /** Sample data: An An <code>LinkedList</code> 
   * of <CODE>{@link Song Song}</CODE> */
  public LinkedList<Song> songlistLL= new LinkedList<Song>();
  public void initSonglistLL(){
    songlistLL.add(song1);
    songlistLL.add(song2);
    songlistLL.add(song3);
  }
  
  
  /**
   * Test the comparison of data in collections that implement the
   * <code>Iterable</code> interface.
   * @param t the <CODE>{@link Tester Tester}</CODE> that performs the tests
   */
  @TestMethod
  public boolean testIterables(Tester t){
    initSonglistAL();
    initSonglist2AL();
    initSonglist3AL();
    initSonglist4AL();
    initSonglistLL();
    
    return
    t.checkExpect(songlistAL, songlist2AL, "same AL songlists - OK") &&

    /** tests that fail */
    t.checkExpect(t.same(songlistAL, songlist3AL), false,
        "different AL songlists - first list is shorter: ") &&  
    t.checkExpect(t.same(songlist3AL, songlistAL), false,
        "different AL songlists - second list is shorter: ") &&  
    t.checkExpect(t.same(songlistAL, songlist4AL), false,
        "different AL songlists - different order of data: ") &&  
    t.checkExpect(t.same(songlistAL, songlistLL), false,
        "same Iterable songlists - different classes of the dataset: ");  
  }
  
  /**
   * Test the comparison of Array data.
   * @param t the <CODE>{@link Tester Tester}</CODE> that performs the tests
   */
  @TestMethod
  public boolean testArrays(Tester t){
    Song[] songlistArr = new Song[]{this.song1, this.song2, this.song3};
    Song[] songlist2Arr = new Song[]{this.song1, this.song2, this.song3};
    Song[] songlist3Arr = new Song[]{this.song1, this.song2};
    Song[] songlist4Arr = new Song[]{this.song1, this.song3, this.song2};
    Book[] booklistArr = new Book[]{this.book1, this.book2, this.book3};
      
    return
    t.checkExpect(songlist2Arr, songlistArr, "same Array-s of songs - OK") &&

    /** tests that fail */
    t.checkExpect(t.same(songlistArr, songlist3Arr), false,
        "different Array-s of songs - first list is shorter: ") &&  
    t.checkExpect(t.same(songlist3Arr, songlistArr), false,
        "different Array-s of songs - second list is shorter: ") &&  
    t.checkExpect(t.same(songlistArr, songlist4Arr), false,
        "different Array-s of songs - different order of data: ") &&  
    t.checkExpect(t.same(songlistArr, booklistArr), false,
        "different Array-s of songs - different classes of the dataset: ");  
  }
  
  /**
   * An example that only determines whether the method invocation 
   * throws the desired exception - and displays the message for this
   * exception
   * 
   * @param t the <CODE>{@link Tester Tester}</CODE> that performs the tests
   */
  @TestMethod
  public boolean testExceptions1(Tester t){
    /** A test that throws an exception */
    try{
      new MTListTr<Object>().getFirst();
      return
      t.checkExpect(false, 
      		"new MTListTr().getFirst() failed to throw an exception");
    }
    catch(UnsupportedOperationException e){
      return
      t.checkExpect(true, "new MTListTr().getFirst() threw exception: \n" 
          + e.getMessage());
    }
  }

  /**
   * Real test for exceptions - this code is not expected to throw an 
   * exception - and the test should fail
   * 
   * @param t the <CODE>{@link Tester Tester}</CODE> that performs the tests
   */
  @TestMethod
  public boolean testExceptions2(Tester t){
    return true;
    /** A test that should not throw an exception */
    /*t.checkExpect(new MTListTr<Object>(),
        "isEmpty",
        new Object[0],
        new UnsupportedOperationException(
            "Cannot access the first element of an empty data set"),
        "new MTListTr().isEmpty() \n" + 
        "The test should fail: the method fails to throw an exception");*/
  }
  
  /**
   * Real test for exceptions - this code is expected to throw an 
   * exception with the given message and the test should succeed
   * 
   * @param t the <CODE>{@link Tester Tester}</CODE> that performs the tests
   */
  @TestMethod
  public boolean testExceptions3(Tester t){
    return
    /** A test that throws an exception */
    t.checkExpect(new MTListTr<Object>(),
        "getFirst",
        new Object[0],
        new UnsupportedOperationException(
            "Cannot access the first element of an empty data set"),
        "new MTListTr().isEmpty() \n" + 
      "Should be success: throws correct exception with the correct message");
  }
  
  /**
   * Real test for exceptions - this code is expected to throw an 
   * exception of the given type but with a different message 
   * - and the test should fail
   * 
   * @param t the <CODE>{@link Tester Tester}</CODE> that performs the tests
   */
  @TestMethod
   public boolean testExceptions4(Tester t){
     return true;
    /** A test that throws an exception */
    /*t.checkExpect(new MTListTr<Object>(),
        "getRest",
        new Object[0],
        new UnsupportedOperationException(
            "Cannot access the first element of an empty data set"),
        "new MTListTr().getFirst() \n" + 
        "The test should fail: we supplied a wrong message");*/
  }


   /**
    * Real test for exceptions - this code is expected to throw an 
    * exception of the type that is different from type of the given 
    * exception - and the test should fail
    * 
    * @param t the <CODE>{@link Tester Tester}</CODE> that performs the tests
    */
  @TestMethod
  public boolean testExceptions5(Tester t){
    return true;
    /** A test that throws an exception */
    /*t.checkExpect(new MTListTr<Object>(),
        "getRest",
        new Object[0],
        new IllegalArgumentException(
            "Cannot access the first element of an empty data set"),
        "new MTListTr().getFirst() \n" + 
        "The test should fail: we supplied a wrong exception class");*/
  }


  /**
   * Tests for the invocation of methods in the user's class, given the 
   * method name and an <CODE>Array</CODE> of method arguments
   * 
   * @param t the <CODE>{@link Tester Tester}</CODE> that performs the tests
   */
  @TestMethod
  public boolean testUserMethods(Tester t){
  	 /*t.checkExpect(this.song1, "shorter", new Object[]{this.song2}, song1,
         "Check if you get the shorter song -- should fail");*/
    return
    t.checkExpect(this.song1, "tenMinutesTotal", 
    		          new Object[]{this.song1a, this.song2}, true,
        "Check if the total playing time is 10 -- should succeed") &&
    t.checkExpect(this.song1, "tenMinutesTotal", 
    		          new Object[]{this.song2, song3}, false,
        "Check if the total playing time is 10 -- it is not, test succeeds") &&
    t.checkExpect(this.song1, "shorter", 
    		          new Object[]{this.song2}, song2,
                  "Check if you get the shorter song -- should succeed") &&
    t.checkExpect(this.song1, "sameTitle", 
        		      new Object[]{"hello"}, false,
        "Check if the song has the given title -- should succeed") &&
    t.checkExpect(this, "nPlus5", 
    		          new Object[]{8}, 13,
                  "Invoke 'this.nPlus5(8)' expect 13 -- should succeed");
    /*t.checkExpect(this, "nPlus6", 
    		          new Object[]{8}, 13,
        "Invoke 'this.nPlus6(8)' expect 13 -- no =such method - fails");*/  
  }
  
  /** 
   * Method to test method invocation within the <code>Examples</code> class
   * @param n the given number
   * @return the given number plus 5
   */
  @SuppressWarnings("unused")
  private int nPlus5(int n){
  	return n + 5;
  }
    
  /** Sample Color data to test correct Color comparison */
  public Color cred = new Color(255, 0, 0);
  public Color cblue = new Color(0, 0, 255);
  
  /** Sample instances of the Sampler class - includes Color field */
  public Sampler sampler1 = new Sampler("Sampler", 2, Color.red);
  public Sampler sampler2 = new Sampler("Sampler", 2, Color.red);
  public Sampler sampler3 = new Sampler("Sampler", 2, Color.red);
 
  /**
   * Tests for different versions of colors - in <CODE>java.awt</CODE>
   * 
   * @param t the <CODE>{@link Tester Tester}</CODE> that performs the tests
   */
  @TestMethod
  public boolean testColors(Tester t){
    return
    // comparing Color objects
    t.checkExpect(cred, new Color(255, 0, 0), "same Color-s OK") &&

    // comparing Color objects
    t.checkExpect(cred, Color.red, "same Color-s OK") &&
    
 // comparing Color objects
    t.checkFail(cred, cblue, "not same Color-s -- fails");
  }
  
  /**
   * Tests for different colors - in <CODE>java.awt</CODE> 
   * - the test should fail
   * 
   * @param t the <CODE>{@link Tester Tester}</CODE> that performs the tests
   */
  @TestMethod
  public boolean testColors2(Tester t){
    return  
    // comparing Color objects
    t.checkFail(cred, new Color(0, 0, 255), "not same Color-s -- fails");
  }
  
  
  /**
   * Tests for different versions of colors - in <CODE>java.awt</CODE> 
   * - the test should fail
   * 
   * @param t the <CODE>{@link Tester Tester}</CODE> that performs the tests
   */
  @TestMethod
  public boolean testColors3(Tester t){
    return  
 // mixing iColor and Color objects
    t.checkFail(cred, Color.blue, 
        "Color red and Color blue - not same - should fail");
  }
  
  /**
   * Tests instances of the Sampler class - the last test should fail
   * 
   * @param t the <CODE>{@link Tester Tester}</CODE> that performs the tests
   */
  @TestMethod
  public boolean testSampleObjects(Tester t){
    return  
    
    // comparing sample objects
    t.checkExpect(sampler1, sampler2, "same samplers") &&
    
    // comparing sample objects
    t.checkExpect(sampler1, sampler3, "not the same samplers -- fails");
  }
  
  /**
   * Instance of an inner class within the Sampler class
   */
  Insider inside1 = sampler1.new Insider("hello", 5);
  
  /**
   * Test for the access to the fields and methods within an inner class
   * 
   * @param t the <CODE>{@link Tester Tester}</CODE> that performs the tests
   */
  @TestMethod
  public boolean testInsider(Tester t){
    return
    t.checkExpect(inside1.combine(), "hello: 5", "Insider combine ") &&
    t.checkExpect(inside1.count(), 10, "Insider count ");
  }

  /**
   * Instance of a package-protected class within the Sampler class
   */
  public Outsider outside1 = new Outsider("hello", 5);
  public String outside1Data = this.outside1.odata;
  public Outsider outside2 = new Outsider("hello2", 5);

  /**
   * Test for the access to the fields and methods within an inner class
   * 
   * @param t the <CODE>{@link Tester Tester}</CODE> that performs the tests
   */
  @TestMethod
  public boolean testOutsider(Tester t){
    return
    t.checkExpect(outside1.outCombine(), "hello: 5", "Outsider combine ") &&
    t.checkExpect(outside1.outCount(), 10, "Outsider count ");
  }

  /* ------------------------------------------------------------------ */
  /* ----- Tests for methods and fields in super class hierarchy ------ */
  /* ------------------------------------------------------------------ */
  /**
   * Data for subclasses with abstract superclasses
   */
  public ALibItem libBook1 = 
    new ALibItemBook("Beach Music", 72, "Pat Conroy");
  public ALibItem libBook2 = 
    new ALibItemBook("The Red Pony", 74, "J. Steinbeck");
  public ALibItem libBook3 = 
    new ALibItemBook("Lords of Discipline", 68, "Pat Conroy");
  
  public ALibItem libAudioBook1 = 
    new ALibItemAudioBook("War and Peace", 82, 12, "Tolstoy");
  public ALibItem libAudioBook2 = 
    new ALibItemAudioBook("The Red Pony", 84, 6, "J. Steinbeck");
  public ALibItem libAudioBook3 = 
    new ALibItemAudioBook("Anna Karenina", 88, 10, "Tolstoy");
 
  public ALibItem libMusic1 = 
    new ALibItemMusic("Carmen", 42, 12, "The Met");
  public ALibItem libMusic2 = 
    new ALibItemMusic("Finlandia", 44, 2, "Sibelius");
  public ALibItem libMusic3 = 
    new ALibItemMusic("Macbeth", 48, 10, "The Met");

  /**
   * A complete test suite for dealing with 
   * abstract and concrete classes and sub/super classes
   * 
   * @param t the <CODE>{@link Tester Tester}</CODE> that performs the tests
   */
  @TestMethod
  public boolean testInheritance(Tester t){
    return
    // test the access to field values of fields defined in the abstract class
    t.checkExpect(this.libBook1.title, "Beach Music",
        "Title field for the class ALibItemBook") &&
    t.checkExpect(this.libAudioBook1.title, "War and Peace",
        "Title field for the class ALibItemAudioBook") &&
    t.checkExpect(this.libMusic1.title, "Carmen",
        "Title field for the class ALibItemMusic") &&
    
    t.checkExpect(this.libBook1.sameTitle("title"), false,
        "Method sameTitle defined in the super class of ALibItemBook") &&
    t.checkExpect(this.libBook1.sameTitle("Beach Music"), true,
        "Method sameTitle defined in the super class of ALibItemBook") &&

    t.checkExpect(this.libBook1.sameLength(), false,
        "Method sameLength defined in the class of ALibItemBook") &&
    t.checkExpect(this.libBook2.sameLength(), true,
        "Method sameLength defined in the class of ALibItemBook") &&

    t.checkExpect(
        ((ALibItemBook)this.libBook1).sameAuthor("title"), false,
        "Method sameAuthor defined in the class of ALibItemBook") &&
    t.checkExpect(((ALibItemBook)this.libBook1).sameAuthor("Pat Conroy"), true,
        "Method sameAuthor defined in the class of ALibItemBook") &&

    
    
    t.checkExpect(this.libAudioBook1.sameTitle("title"), false,
        "Method sameTitle defined in the super class of ALibItemAudioBook") &&
    t.checkExpect(this.libAudioBook1.sameTitle("War and Peace"), true,
        "Method sameTitle defined in the super class of ALibItemAudioBook") &&

    t.checkExpect(this.libAudioBook1.sameLength(), false,
        "Method sameLength defined in the class of ALibItemAudioBook") &&
    t.checkExpect(this.libAudioBook2.sameLength(), true,
        "Method sameLength defined in the class of ALibItemAudioBook") &&

    t.checkExpect(((ALibItemAudioBook)this.libAudioBook1).sameAuthor("title"),
    		false,
        "Method sameAuthor defined in the class of ALibItemAudioBook") &&
   t.checkExpect(((ALibItemAudioBook)this.libAudioBook1).sameAuthor("Tolstoy"),
    		true,
        "Method sameAuthor defined in the class of ALibItemAudioBook") &&
          
    t.checkExpect(this.libMusic1.sameTitle("title"), false, 
        "Method sameTitle defined in the super class of ALibItemMusic") &&
    t.checkExpect(this.libMusic1.sameTitle("Carmen"), true,
        "Method sameTitle defined in the super class of ALibItemMusic") &&

    t.checkExpect(this.libMusic1.sameLength(), false,
        "Method sameLength defined in the class of ALibItemMusic") &&
    t.checkExpect(this.libMusic3.sameLength(), true, 
        "Method sameLength defined in the class of ALibItemMusic") &&

    t.checkExpect(((ALibItemMusic)this.libMusic1).sameArtist("title"), false,
        "Method sameArtist defined in the class of ALibItemMusic") &&
    t.checkExpect(((ALibItemMusic)this.libMusic1).sameArtist("The Met"), true,
        "Method sameArtist defined in the class of ALibItemMusic")&&
        
    t.checkFail(this.libBook1, this.libBook2,
            "Different books - check printing of values in test cases") ; 
  }
   
  //----- The main test driver - invokes each of the above test methods -----//
  //-------- It includes inline test cases for the user-defined lists -------//

  /** 
   * Additional test cases.
   * 
   * @param t the <CODE>{@link Tester Tester}</CODE> that performs the tests
   */
  @TestMethod
  public boolean testMore(Tester t){ 
    
    return
    
    //----- Comparisons of lists of data - shown inline as an option ------//
    
    /** Comparisons of lists of data - illustrating two comparison options */
    t.checkExpect(t.same(songlist, songlist2), true, "same songlists") &&
    t.checkExpect(songlist, songlist2, "same songlists - direct") &&

    /** Additional tests for the list equality: */
    t.checkExpect(t.same(songlist, songlist3), false, 
      "different songlists -- first one is longer") &&
    t.checkExpect(t.same(songlist3, songlist2), false,
        "different songlists -- first one is shorter") &&
    t.checkExpect(t.same(songlist, songlist1), false,
        "different songlists -- data in different order") &&
    t.checkExpect(t.same(songlist, booklist), false,
        "different songlists -- contain different datatypes") &&
        
    /** Tests for the method 'contains' in the classes <code>AList</code> */
    t.checkExpect(songlist.contains(song1), true, "songlist contains 1") &&
    t.checkExpect(booklist.contains(book4), false,"songlist contains 2") &&
    
    /** A test that fails */
    t.checkFail(songlist, songlist3, "same songlists - will fail");
    
    /** throw a runtime exception - never reached */
   //t.checkExpect(1/0, 1);
 
  }
  
  @TestMethod
  public boolean testNoTestname(Tester t){
    return 
    /** A test that fails */
    t.checkFail(5, 8);
  }

  /**
   * Run all tests provided by the user.
   */
  public void go(){
    //Tester tester = new Tester();
    //tester.runTests(this);

    System.out.println("---------------------------------------------------");
    System.out.println(
    		"\n Displaying fields - outside of the 'tests' method: \n");
    System.out.println(
    		"outsider1: " + Printer.produceString(this.outside1));
    System.out.println(
    		"book4.author: " + Printer.produceString(book4.author));
    System.out.println(
    		"book4: " + Printer.produceString(book4));
    System.out.println(
    		"\n songlist3AL: " + Printer.produceString(songlist3AL));
    System.out.println(
    		"\n songlistLL: " + Printer.produceString(songlistLL));

    System.out.println("\n libBook3: " + Printer.produceString(libBook3));
    System.out.println("\n libMusic1: " + Printer.produceString(libMusic1));

  }
  
  /**
   * <P>Display all data defined in the <CODE>{@link Examples Examples}</CODE> 
   * class.</P>
   * <P>Run all tests defined in the <CODE>{@link Examples Examples}</CODE> 
   * class.</P>
   */
  public static void main(String[] argv){
    Examples e = new Examples();

    System.out.println("Show all data defined in the Examples class:");
    //System.out.print(Printer.produceString(e));

    System.out.println("\n\n---------------------------------------------------");
    System.out.println("Invoke tester.runTests(this):");
    
    //e.go();
    Tester.runReport(e, true, true);
  }

}